﻿using System;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI;
using CaptchaMvc.Attributes;
using noteVt.Helpers;
using noteVt.Models.DataModels;

namespace noteVt.Controllers
{
    public class ArticleController : Controller
    {
        private readonly MainContext _dbContext = new MainContext();

        [OutputCache(Duration = 5, Location = OutputCacheLocation.ServerAndClient)]
        public ActionResult Index(string idOrAlias)
        {
            Article article;
            try
            {
                Guid idIfParse;
                article = Guid.TryParse(idOrAlias, out idIfParse)
                              ? _dbContext.Articles.Single(art => art.Id == idIfParse)
                              : _dbContext.Articles.Single(art => art.Alias == idOrAlias);
            }
            catch
            {
                return View("404");
            }
            return View((Object) article.ArticleContent);
        }
        
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost, CaptchaVerify("Captcha is not valid")]
        [ValidateInput(false)]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Article newArticle)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    bool hasAlias = newArticle.Alias != null;
                    newArticle.Id = Guid.NewGuid();
                    newArticle.EditLink = Guid.NewGuid();
                    newArticle.CreateDate = DateTime.Now;
                    newArticle.LastEditDate = DateTime.Now;
                    newArticle.Alias = hasAlias ? newArticle.Alias : Guid.NewGuid().ToString();
                    newArticle.ArticleContent = newArticle.ArticleContent.CleanHtml();
                    _dbContext.Articles.Add(newArticle);
                    _dbContext.SaveChanges();

                    TempData["editId"] = newArticle.EditLink.ToString();
                    TempData["viewId"] = hasAlias ? newArticle.Alias : newArticle.Id.ToString();
                    return RedirectToAction("ViewCreated");
                }
                catch 
                {
                    return View(newArticle);
                }
            }
            return View(newArticle);
        }

        public ActionResult ViewCreated()
        {
            if (TempData["editId"] == null)
            {
                return RedirectToAction("Index", "Home");
            }
            var model = new string[2];
            model[0] = String.Format("{0}://{1}/{2}", Request.Url.Scheme, Request.Url.Authority, TempData["viewId"]);
            model[1] = String.Format("{0}://{1}{2}/{3}", Request.Url.Scheme, Request.Url.Authority,
                                               Url.Action("Edit"), TempData["editId"]); 
            return View(model);
        }

        public ActionResult Edit(string editId)
        {
            if (editId == null)
            {
                return RedirectToAction("Index", "Home");
            }
            Guid idIfParse;
            Article article;
            Guid.TryParse(editId, out idIfParse);
            try
            {
                article = _dbContext.Articles.Single(art => art.EditLink == idIfParse);
                Guid parseGuid;
                if (Guid.TryParse(article.Alias, out parseGuid))
                {
                    article.Alias = null;
                }
            }
            catch
            {
                return View("404");
            }
            return View(article);
        }
        
        [HttpPost]
        [ValidateInput(false)]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Article editArticle)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    bool hasAlias = editArticle.Alias != null;
                    editArticle.Alias = hasAlias ? editArticle.Alias : new Guid().ToString();
                    editArticle.LastEditDate = DateTime.Now;
                    editArticle.ArticleContent = editArticle.ArticleContent.CleanHtml();

                    _dbContext.Articles.Attach(editArticle);
                    _dbContext.Entry(editArticle).Property(a => a.ArticleContent).IsModified = true;
                    _dbContext.Entry(editArticle).Property(a => a.LastEditDate).IsModified = true;
                    _dbContext.Entry(editArticle).Property(a => a.Alias).IsModified = true;
                    _dbContext.SaveChanges();

                    TempData["editId"] = Request.Url.Segments[Request.Url.Segments.Count() - 1];
                    TempData["viewId"] = hasAlias ? editArticle.Alias : editArticle.Id.ToString();
                    return RedirectToAction("ViewCreated");
                }
                catch
                {
                    return View(editArticle);
                }
            }
            return View(editArticle);
        }
    }
}